﻿using FinScreen.Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reactive.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using FinScreen.Util;
using System.Reactive.Subjects;

namespace FinScreen
{
    class QuantBase : Observable<Instrument>
    {
        public void Load(IEnumerable<Instrument> instruments)
        {
            foreach (var instrument in instruments.AsParallel())
            {
                var quotes = ParseQuoteSeries(instrument);
                if (quotes != null && quotes.Count > 0)
                {
                    instrument.Quotes.AddRange(quotes);
                    OnNext(instrument);
                }
            }
        }

        private ICollection<Quote> ParseQuoteSeries(Instrument instrument)
        {
            List<Quote> series = new List<Quote>();

            var lines = new string[] { "SS", "SZ" }
                .Select(exchange =>
                    System.IO.Path.Combine(@"D:\FinData\Quotes",
                    string.Format(@"{0}{1}.txt", exchange == "SS" ? "SH" : exchange, instrument.Code.Replace("." + exchange, ""))))
                .Where(p => File.Exists(p))
                .Select(p => File.ReadLines(p, Encoding.GetEncoding("GB2312")))
                .SingleOrDefault();

            if (lines == null)
                return null;

            Quote prevQuote = null;
            foreach (var line in lines)
            {
                Quote quote = ParseQuote(instrument, line);
                if (quote == null || quote.TS == DateTime.MinValue)
                    continue;
                if (prevQuote != null)
                {
                    quote.PrevClose = prevQuote.Close;
                    quote.PctChange = Math.Round((quote.Close - prevQuote.Close) / prevQuote.Close * 100, 2);
                    quote.NetChange = (quote.Close - prevQuote.Close);
                }
                else
                {
                    quote.PrevClose = quote.Close;
                    quote.PctChange = 0;
                    quote.NetChange = 0;
                }

                prevQuote = quote;

                series.Add(quote);
            }

            return series;
        }
        private Quote ParseQuote(Instrument instruement, string line)
        {
            var splits = line.Split('\t');
            if (splits.Length < 6)
                return null;

            return new Quote()
            {
                TS = splits[0].ToDateTime() ?? DateTime.MinValue,
                Open = splits[1].ToDouble() ?? 0,
                High = splits[2].ToDouble() ?? 0,
                Low = splits[3].ToDouble() ?? 0,
                Close = splits[4].ToDouble() ?? 0,
                Volume = splits[5].ToDouble() ?? 0,
                TurnOver = splits[6].ToDouble() ?? 0,
                LastPrice = splits[4].ToDouble() ?? 0
            };
        }
    }
}
